#pragma once
#include "ribbonview.h"
#include "RibbonResultView.h"
#include "RibbonColorSetter.h"

#define RIBBONRESULTMANAGERVIEW_WNDCLASS L"RIBBONRESULTMANAGERVIEW"

LRESULT CALLBACK RibbonResultsManagerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

//This is not a pure COM object since it exposes C++ function not through COM interface. It is a violation of COM isolation
//But it makes it easy to use C++ types
class CRibbonResultManagerView :
	public CRibbonView, public ICloseEvent
{
	friend LRESULT CALLBACK RibbonResultsManagerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

private:
	CComObject<CRibbonResultView> *m_pRibbonResultView;
	CComObject<CRibbonColorSetter> *m_pBackgroundColor;
	CComObject<CRibbonColorSetter> *m_pHighlightColor;
	CComObject<CRibbonColorSetter> *m_pTextColor;

	shared_ptr<CRibbonInfo> m_ribbonInfo;
	CPropertyReader m_propertyReader; 

	wstring m_szResourceDllName;
	PCWSTR m_szRibbonResourceName;
	HMODULE m_hRibbonResourseModule;
	HWND m_hWnd;
	HWND m_hRibbonResultViewWnd;
	INT32 m_currentApplicationMode;
	UINT32 m_currentCommandItemId;
	PROPERTYKEY m_currentPropertyKey;
	bool m_bLoadEnabled;

	//Command Ids
	UINT32 cmdCommandSelection;
	UINT32 cmdPropertyKeySelection;
	UINT32 cmdInvalidateState;
	UINT32 cmdInvalidateValue;
	UINT32 cmdInvalidateProperty;
	UINT32 cmdInvalidateAllProperty;
	UINT32 cmdGetProperty;
	UINT32 cmdSetProperty;
	UINT32 cmdSetStringValue;
	UINT32 cmdSetNumericValue;
	UINT32 cmdSetBooleanValue;
	UINT32 cmdUseSetValues;
	UINT32 cmdSaveState;
	UINT32 cmdLoadState;
	UINT32 cmdBackgroundColor;
	UINT32 cmdHighlightColor;
	UINT32 cmdTextColor;

	wstring m_currentSetStringValue;
	double m_currentSetNumericValue;
	bool   m_currentSetBooleanValue;
	bool   m_bUseSetValues;
	
	enum CommandRanges
	{
		CommandRangeContextualTab = 1000,
		CommandRangeContextPopup = 2000,
		CommandRangeApplicationMode = 3000,
		CommandRangeEnd = 4000
	};

	static CRibbonResultManagerView *s_pRibbonResultManagerView;
	void GenerateCommands(wostringstream &text,
						  const vector<int> &v, const wstring &prefix,
						  int rangeStart);
	void GenerateApplicationModeCommands(wostringstream &text);
	void GenerateContextPopupDropDownButton(wostringstream &text);
	void GenerateContextualTabCheckBoxButtons(wostringstream &text);
	void GenerateApplicationModeCheckBoxButtons(wostringstream &text);
	void ExecuteContextualTabCommand(int nCmdID, const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue);
	void ExecuteContextPopupCommand(int nCmdID, const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue);
	void ExecuteApplicationModeCommand(int nCmdID, const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue);
	void OnClose();
	void InitRibbonCommandItem(IUICollection* pCollection, const wstring &commandName);
	void InitPropertyKeyItem(IUICollection* pCollection, const pair<PROPERTYKEY, wstring> &propertyKeyPair);
	bool CompareSecond(pair<PROPERTYKEY, wstring> pair1, pair<PROPERTYKEY, wstring> pair2);


protected:
		STDMETHOD(OnAfterCreateRibbon)(HWND hWnd, HINSTANCE hInstance);

public:
	wstring GenerateResultManagerRibbon();
	void SetParameters(const shared_ptr<CRibbonInfo> &ribbonInfo, const wstring &szResourceDllName, PCWSTR szRibbonResourceName);
	CRibbonResultManagerView(void);
	~CRibbonResultManagerView(void);
	
	STDMETHOD(OnCreateUICommand)(UINT32 nCmdID, __in UI_COMMANDTYPE typeID, __deref_out IUICommandHandler** ppCommandHandler);
   	STDMETHOD(OnViewChanged)(UINT32 nViewID, __in UI_VIEWTYPE typeID, __in IUnknown* pView, UI_VIEWVERB verb, INT32 uReasonCode);  

	STDMETHOD(Execute)(UINT nCmdID,
		UI_EXECUTIONVERB verb, 
		__in_opt const PROPERTYKEY* key,
		__in_opt const PROPVARIANT* ppropvarValue,
		__in_opt IUISimplePropertySet* pCommandExecutionProperties);

	STDMETHOD(UpdateProperty)(UINT nCmdID,
		__in REFPROPERTYKEY key,
		__in_opt const PROPVARIANT* ppropvarCurrentValue,
		__out PROPVARIANT* ppropvarNewValue);


	static void RegisterClass(HINSTANCE hInstance);

	

};

//For sorting the UI_PKEY_* ComboBox
template<>
struct less<pair<PROPERTYKEY, wstring>>
	: public binary_function<const pair<PROPERTYKEY, wstring> &, const pair<PROPERTYKEY, wstring> &, bool>
{	// functor for operator<
	bool operator()(const pair<PROPERTYKEY, wstring> &pair1, const pair<PROPERTYKEY, wstring> & pair2) const
	{	// apply operator< to operands
		return pair1.second < pair2.second;
	}
};
	